﻿using System;
using System.Linq;
using System.Web.UI.WebControls;

namespace MSTR.IS.Util
{
    public static class Loader
    {
        /// <summary>
        /// Set list control selection with the 1st valid value.
        /// </summary>
        /// <param name="lc">The list control.</param>
        /// <param name="orderedValues">Values in order.</param>
        /// <exception cref="ArgumentNullException" />
        /// <exception cref="ArgumentException" />
        public static void Select(this ListControl lc, params string[] orderedValues)
        {
            if (null == lc)
                throw new ArgumentNullException("lc");

            if (null == orderedValues || 0 == orderedValues.Length)
                throw new ArgumentException("At least specify one value for chaning the selection.", "orderedValues");

            lc.ClearSelection();

            if (0 == lc.Items.Count)
                return;

            foreach (var value in orderedValues)
            {
                if (null != value && null != lc.Items.FindByValue(value))
                {
                    lc.SelectedValue = value;
                    break;
                }
            }
        }

        public static void Select(this ListControl lc, int? intValue)
        {
            var sValue = null == intValue ? null : intValue.Value.ToString();
            Select(lc, sValue);
        }

        public static void Select(this ListControl lc, bool? boolValue)
        {
            var sValue = null == boolValue ? null : boolValue.Value.ToString().ToLower();
            Select(lc, sValue);
        }

        /// <summary>
        /// Bind data for list control.
        /// </summary>
        /// <param name="lc">The list control to bind.</param>
        /// <param name="dataSource">The data source object.</param>
        /// <param name="dataValueField">The field of the data source that provides the value of each list item.</param>
        /// <param name="dataTextField">The field of the data source that provides the text content of the list items.</param>
        /// <param name="insertEmptyItem">Whether to insert an empty item to the first position of list while binding.</param>
        /// <exception cref="ArgumentNullException" />
        public static void Bind(this ListControl lc, object dataSource, string dataValueField, string dataTextField, bool insertEmptyItem)
        {
            if (null == lc)
                throw new ArgumentNullException("lc");

            lc.Items.Clear();
            if (insertEmptyItem)
            {
                lc.Items.Add(new ListItem());
                lc.AppendDataBoundItems = true;
            }

            if (null != dataSource)
            {
                lc.DataSource = dataSource;
                lc.DataValueField = dataValueField;
                lc.DataTextField = dataTextField;
                lc.DataBind();
            }
        }

        /// <summary>
        /// Remove items from list control by value.
        /// </summary>
        /// <param name="lc">The list control.</param>
        /// <param name="removeValues">The value collection of items to remove.</param>
        /// <exception cref="ArgumentNullException" />
        /// <exception cref="ArgumentException" />
        public static void RemoveLI(this ListControl lc, params string[] removeValues)
        {
            if (null == lc)
                throw new ArgumentNullException("lc");

            if (null == removeValues || 0 == removeValues.Length)
                throw new ArgumentException("At least specify one value of list item to remove.", "removeValues");

            if (0 == lc.Items.Count)
                return;

            var index = 0;
            while (index < lc.Items.Count)
            {
                var curValue = lc.Items[index].Value;
                if (removeValues.Any(it => 0 == string.Compare(curValue, it, true)))
                    lc.Items.RemoveAt(index);
                else
                    index++;
            }
        }

        /// <summary>
        /// Keep items by value and remove others from list control.
        /// </summary>
        /// <param name="lc">The list control.</param>
        /// <param name="exceptValues">The value collection of items to keep.</param>
        /// <exception cref="ArgumentNullException" />
        /// <exception cref="ArgumentException" />
        public static void RemoveLIExcept(this ListControl lc, params string[] exceptValues)
        {
            if (null == lc)
                throw new ArgumentNullException("lc");

            if (null == exceptValues || 0 == exceptValues.Length)
                throw new ArgumentException("At least specify one value of list item to keep.", "exceptValues");

            if (0 == lc.Items.Count)
                return;

            var index = 0;
            while (index < lc.Items.Count)
            {
                var curValue = lc.Items[index].Value;
                if (exceptValues.Any(it => 0 == string.Compare(curValue, it, true)))
                    index++;
                else
                    lc.Items.RemoveAt(index);
            }
        }
    }
}
